<template>
	<view>
		<z-cropper v-if="cropper" @ok="uploadFile($event, emit)" ref="cropper" mode="fixed" :=cropperPrams />

		<view class="imgList" style="color: #333;" v-if="!hide">
			<input type="text" :name="name" v-if="up" :value="value" style="width: 0;height: 0;overflow: hidden;">
			<view :style="[style]" @click="lookImg(item,index)" v-for="(item,index) in list" :key="index"
				class="pr imgBox center_box" :class="{'img_border':img_border}">
				<block v-if="type=='video'">
					<image :src="oss(item.path)" class="pa left0 top0 w-max h-max" :mode="imageMode" v-if="isOss"
						:style="[{'border-radius':radius+'rpx'}]" />
					<view class="w-max h-max center_box pr" style="background-color: #0006;"
						@click="video_url=item.path">
						<text style="color: #fff;" :style="{fontSize:(iconSize||size/4)+'rpx'}">▶</text>
					</view>
				</block>
				<block v-else>
					<image class="w-max h-max" :src="item.path" :mode="imageMode"
						:style="[{'border-radius':radius+'rpx'}]" :show-menu-by-longpress="showMenuByLongpress" />
				</block>
				<view class="">
					<view @click.stop="del(index)" v-if="up" class="close">×</view>
				</view>
			</view>
			<view :style="[style]" v-if="(up)&&list.length<max*1" class="imgBox center_box "
				:class="{'img_border':img_border}" @click="setimg()" style="text-align: center;line-height: 1em;">
				<block v-if="upSrcImg">
					<image :src="upSrcImg" class="w-max h-max" mode="scaleToFill"></image>
				</block>
				<block v-else>
					<view :style="{fontSize:(iconSize||size/3)+'rpx'}">+</view>
					<view :style="{fontSize:(textSize||size/9)+'rpx'}">{{text||(type=='video'?'上传视频':'上传照片')}}</view>
				</block>
			</view>
			<view v-if="video_url" @click="video_url=''"
				style="position: fixed; width: 100vw;height: 100vh;top: 0;left: 0; background: #000d;z-index: 998;">
				<view class="w-max " @click.stop=""
					style="position: absolute;top: 50%;left: 0; transform: translate(0,-50%);">
					<video autoplay :src="video_url" class="w-max h750" loop />
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	/**
	 * z-imgs 超级图片组件
	 * @description 集成了图片列表 图片点击放大 图片上传 图片回显 图片剪切 上传视频 视频查看 
	 * @tutorial 张浩
	 * @property {String} size 图片大小 单位rpx 默认200
	 * @property {String} width 图片宽度 不填写则取size
	 * @property {String} height 图片高度 不填写则取size
	 * @property {String} paths 回显图片(主要)
	 * @property {String} pathName 取对象内图片字段字段
	 * @property {String} ids 回显id 用作上传功能
	 * @property {String} idName 取对象内图片id字段
	 * @property {String} up 开启上传功能
	 * @property {String} textSize 上传照片 文字大小
	 * @property {String} iconSize 图标 文字大小
	 * @property {String} upSrcImg 上传组件默认展示图片
	 * @property {String} max 上传图片数量 默认1
	 * @property {String} type img 上传图片  video视频 默认 img
	 * @property {String} isOss 后端做了oss才能开启 可以回显视频第一秒 默认关闭
	 * @property {String} hide 是否隐藏组件 默认false  
	 * @property {String} hideBor 是否隐藏
	 * @property {String} text 修改 "上传图片"  文本
	 * @property {String} cropper 剪切功能
	 * @property {String} cropperPrams 剪切功能内部参数
	 * @property {String} look 开启查看图片功能
	 * @property {String} margin 图片间距
	 * @example <z-imgs /> 
	 * @example @click="$refs.img.uplode('getImg')" <z-imgs @success="ids=$event" />
	 */

	export default {
		name: "z-imgs",
		props: {
			name: { //表单对外name
				default: '',
			},
			size: { //图片大小
				default: '200',
			},
			width: { //图片宽度 
				default: ''
			},
			height: { //图片高度
				default: ''
			},
			paths: { //回显图片(主要)
				default: '',
			},
			pathName: { //取对象内图片字段字段
				type: String,
				default: '',
			},
			ids: { //回显id 用作上传功能
				default: '',
			},
			idName: { //取对象内图片id字段
				type: String,
				default: '',
			},
			up: { //开启上传功能
				type: Boolean,
				default: false,
			},

			textSize: { //上传照片 文字大小
				default: 0,
			},
			iconSize: { //图标 文字大小
				default: 0,
			},
			upSrcImg: { //上传组件默认展示图片
				default: ''
			},
			max: { //上传图片数量
				default: 1
			},
			type: { //img 上传图片  video视频 默认 img
				default: 'img', //video  视频
			},
			isOss: { //后端做了oss才能开启 可以回显视频第一秒 默认关闭
				type: Boolean,
				default: false,
			},
			hide: { //是否隐藏组件 默认false  
				type: Boolean,
				default: false,
			},
			hideBor: { //是否隐藏border
				type: Boolean,
				default: false,
			},
			text: { //修改 "上传图片"  文本
				default: '',
			},
			cropper: { //剪切功能
				type: Boolean,
				default: false,
			},
			cropperPrams: { //剪切功能内部参数
				type: Object,
				// default: '', //剪切
			},
			look: { //开启查看图片功能
				type: Boolean,
				default: false,
			},
			imageMode: { //预览上传的图片时的裁剪模式，和image组件mode属性一致
				type: String,
				default: 'aspectFill',
			},
			showMenuByLongpress: {
				type: Boolean,
				default: false,
			},
			margin: { //图片间距
				type: [String, Number],
				default: '10',
			},
			radius: { //图片圆角
				type: [String, Number],
				default: 4,
			},
		},
		computed: {
			style() {
				return {
					"width": (this.width || this.size) + 'rpx',
					"height": (this.height || this.size) + 'rpx',
					"margin-right": this.margin + 'rpx',
					"margin-button": this.margin + 'rpx',
				}
			},
			img_border() {
				return this.up && !this.hideBor
			}
		},
		data() {
			return {
				list: [], //内部显示的图片数组 [{id:1,path:'https//img.png'}]
				value: '', //form 组件配合使用
				emit: '',
				video_url: ''
			};
		},
		watch: {
			// ids: {
			// 	handler(val1, val2) {
			// 		this.setPaths()
			// 	},
			// 	immediate: true
			// },
			paths: {
				handler(val1, val2) {
					this.setPaths()
				},
				immediate: true
			},
		},
		created() {
			// this.setInit()
		},
		methods: {

			setPaths() {
				let paths = this.paths
				if (!paths) return
				if (typeof paths === 'string') paths = [this.paths]

				let ids = this.ids || ''
				if (ids && typeof ids === 'number') ids = ids.toString()
				if (ids && typeof ids === 'string') ids = ids.split(',')

				Object.values(paths).map((item, index) => {
					this.list[index] = this.list[index] || {}
					let path = item[this.pathName] || item || ""
					if (typeof path !== 'string') path = ''
					this.list[index].path = path
					if (ids[index]) this.list[index].id = ids[index][this.idName] || ids[index]
				})

				this.list = this.list.filter(e => e.path)
				if (this.up) this.success()
			},
			lookImg(item, index) {
				this.$emit('click', index)
				if (!(this.up || this.look)) return
				let urls = this.list.map(e => e.path)
				if (this.type == 'img') {
					uni.previewImage({
						urls,
						current: index
					})
				} else if (this.type == 'video') {
					// uni.navigateTo({
					// 	url: '/pages/public/video?src=' + item.path
					// })
				}
			},
			oss(url, t = 1000) {
				let image = '';
				image = url + `?x-oss-process=video/snapshot,t_${t},m_fast`
				return image;
			},
			setimg() {
				if (this.type == "video") { //视频
					this.upVideo('')
				} else { //图片
					let count = this.max - this.list.length
					this.upImg('', count)
				}
			},
			del(index) {
				let that = this
				uni.showModal({
					title: '删除',
					content: "确认删除吗",
					success(res) {
						if (res.confirm) {
							that.list.splice(index, 1)
							that.success()
						}
					}
				})
			},
			success() {
				let ids = this.list.map(item => {
					return item.id
				})
				ids = ids.toString()
				this.value = ids
				this.$emit('success', ids, this.list)
				return ids
			},
			upImg(emit = '', count = 1) {
				this.emit = emit
				if (this.cropper && this.$refs.cropper) return this.$refs.cropper.open()
				uni.chooseImage({
					count, //最多可以选择的图片张数，默认9
					success: (e) => {
						e.tempFilePaths.map(item => {
							this.uploadFile(item, emit)
						})
					}
				})
			},
			upVideo(emit) { //上传视频
				uni.chooseVideo({
					success: (e) => {
						this.uploadFile(e.tempFilePath, emit)
					}
				})
			},
			up_data(emit, res) {
				if (emit) this.$emit(emit, res)
				let item = {}
				item.id = res.id
				item.path = res.path
				this.list.push(item)
				this.success()
			},
			uploadFile(filePath, emit = '') {
				let token = uni.getStorageSync('token')
				let url = '/system/basic/uploadImage' //此处修改接口
				let name = 'img'
				// if (this.type == 'video') {
				// 	url = '/system/upload/ossUpload'
				// 	name = 'file'
				// }
				let downloadTask = uni.uploadFile({
					header: {
						Authorization: token,
						token: token,
					},
					url: this.$baseUrl + url, //仅为示例，非真实的接口地址
					filePath,
					fileType: "image",
					name,
					success: (res) => {
						if (res.statusCode == 200) { //上传成功

							res = JSON.parse(res.data)
							if (res.code == 0) {
								uni.showToast({
									icon: "none",
									title: res.info + ''
								})
								return
							}
							uni.showToast({
								// icon: "none",
								title: '上传成功'
							})
							let data = {
								id: res.id || "",
								path: res.path
							}
							// if (this.type == 'video') {
							// 	data = {
							// 		id: res.data.url || "",
							// 		path: res.data.url
							// 	}
							// }
							this.up_data(emit, data)
							// this.up_data()
						} else {
							uni.showToast({
								icon: "none",
								title: res.statusCode + ''
							})
							console.error(res.data)
						}
					},
					fail() {
						console.error('查看下此处配置有无问题');
					},
					complete() {
						uni.hideLoading()
					}
				});
				uni.showLoading({
					title: '开始上传'
				})
				downloadTask.onProgressUpdate((res) => { //监听下载进度
					console.log('上传进度' + res.progress);
					// console.log('已经下载的数据长度' + res.totalBytesWritten);
					// console.log('预期需要下载的数据总长度' + res.totalBytesExpectedToWrite);
					// 满足测试条件，取消下载任务。
					// num = res.progress
					// tit = `  资源加载中:${num}%`
					// wobj.setTitle(tit);
					uni.showLoading({
						title: '上传进度' + res.progress
					})
					if (res.progress == '100') {
						uni.showToast({
							// icon: "none",
							title: '上传成功'
						})
					}
				});
			}
		}
	}
</script>

<style lang="scss" scoped>
	.imgList {
		box-sizing: border-box;
		display: flex;
		flex-direction: row;
		flex-wrap: wrap;
		align-items: center;

		margin: 0 -10rpx -10rpx 0; //////////

		// overflow: hidden;
		.imgBox {
			margin: 10rpx;

			margin: 0 10rpx 10rpx 0; //////////


			border-radius: 10rpx;
			// overflow: hidden;
			color: #606266;
		}

		.center_box {
			display: flex;
			flex-direction: column;
			justify-content: space-evenly;
			align-items: center;
		}

		.img_border {
			border: #dddddd dashed 2rpx;
		}

		.close {
			position: absolute;
			top: -8rpx;
			right: -8rpx;
			width: 30rpx;
			height: 30rpx;
			border-radius: 100%;
			line-height: 30rpx !important;
			text-align: center;
			color: #fff;
			background: red;

			// .view {
			// 	position: absolute;
			// 	top: 50%;
			// 	left: 50%;
			// 	transform: translate(-50%, -50%);
			// }
		}

		.pa {
			position: absolute;
		}

		.pr {
			position: relative;
		}

		.w-max {
			width: 100%;
		}

		.h-max {
			height: 100%;
		}
	}
</style>